package com.lemon.cloud.xxl;

import cn.hutool.core.util.StrUtil;
import com.lemon.cloud.xxl.properties.XxlAdminProperties;
import com.lemon.cloud.xxl.properties.XxlExecutorProperties;
import com.lemon.cloud.xxl.properties.XxlJobProperties;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import com.xxl.job.core.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import java.util.stream.Collectors;

/**
 * @author HuangDS
 */
@Slf4j
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EnableConfigurationProperties(XxlJobProperties.class)
public class XxlJobAutoConfiguration {

    private static final String XXL_JOB_ADMIN = "xxl-job-admin";

    /**
     * 自定注册只会到 xxl_job_registry表内，用户任然需要到 执行器管理页面添加执行器，不过不需要添加 ‘机器地址’，会自动检查的
     * @param environment
     * @param xxlJobProperties
     * @param discoveryClient
     * @return
     */
    @Bean(initMethod = "start", destroyMethod = "destroy")
    public XxlJobSpringExecutor xxlJobExecutor(Environment environment, XxlJobProperties xxlJobProperties,
                                               DiscoveryClient discoveryClient) {
        log.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        XxlAdminProperties admin = xxlJobProperties.getAdmin();
        XxlExecutorProperties executor = xxlJobProperties.getExecutor();
        String appName = environment.getProperty("spring.application.name");
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setAccessToken(executor.getAccessToken());
        xxlJobSpringExecutor.setLogPath(executor.getLogPath());
        xxlJobSpringExecutor.setLogRetentionDays(executor.getLogRetentionDays());
        if (!StringUtils.hasText(admin.getAddresses())) {
            String serverList = discoveryClient.getServices().stream().filter(s -> s.contains(XXL_JOB_ADMIN))
                    .flatMap(s -> discoveryClient.getInstances(s).stream()).map(instance -> String
                            .format("http://%s:%s/%s", instance.getHost(), instance.getPort(), XXL_JOB_ADMIN))
                    .collect(Collectors.joining(StrUtil.COMMA));
            xxlJobSpringExecutor.setAdminAddresses(serverList);
        } else {
            xxlJobSpringExecutor.setAdminAddresses(admin.getAddresses());
        }
        if (StrUtil.isEmpty(executor.getIp())){
            xxlJobSpringExecutor.setIp(IpUtil.getIp());
        }else {
            xxlJobSpringExecutor.setIp(executor.getIp());
        }
        xxlJobSpringExecutor.setPort(executor.getPort());
        return xxlJobSpringExecutor;
    }
}
